#include "CurtainServer.h"
#include "HttpCmdProcess.h"
#include "Protocol/ProtocolApi.h"
#include "errorCode.h"
#include "ScreenMirrorStream.h"

using namespace Protocol;
CurtainServer *CurtainServer::s_CurtainServer = nullptr;

void CurtainServerInit(){
	CurtainServer::instance();
} 

CurtainServer::CurtainServer(){
	RegistRPC();
}

void CurtainServer::RegistRPC(){
	RPCMethodMap method_map;
    method_map.emplace("GetDeviceCapacity", CRPCFuntion::CreateRpc([this](const Json::Value &request, const BufferMap::Ptr &inMap, Json::Value &response, BufferMap::Ptr &outMap){
        return GetDeviceCapacity(request, inMap, response, outMap);
	}, false));

	method_map.emplace("GetStreamType", CRPCFuntion::CreateRpc([this](const Json::Value &request, const BufferMap::Ptr &inMap, Json::Value &response, BufferMap::Ptr &outMap){
        return GetStreamType(request, inMap, response, outMap);
	}, false));

	method_map.emplace("SetCurtainLayout", CRPCFuntion::CreateRpc([this](const Json::Value &request, const BufferMap::Ptr &inMap, Json::Value &response, BufferMap::Ptr &outMap){
        return SetCurtainLayout(request, inMap, response, outMap);
	},false));

	method_map.emplace("GetCurtainLayout", CRPCFuntion::CreateRpc([this](const Json::Value &request, const BufferMap::Ptr &inMap, Json::Value &response, BufferMap::Ptr &outMap){
        return GetCurtainLayout(request, inMap, response, outMap);
	}, false));

	method_map.emplace("SetPlayStrategy", CRPCFuntion::CreateRpc([this](const Json::Value &request, const BufferMap::Ptr &inMap, Json::Value &response, BufferMap::Ptr &outMap){
        return SetPlayStrategy(request, inMap, response, outMap);
	}, false));

	method_map.emplace("SetDeviceShareStatus", CRPCFuntion::CreateRpc([this](const Json::Value& request, const BufferMap::Ptr& inMap, Json::Value& response, BufferMap::Ptr& outMap) {
		return SetDeviceShareStatus(request, inMap, response, outMap);
	}, false));

    method_map.emplace("GetOutputInterface", CRPCFuntion::CreateRpc([this](const Json::Value &request, const BufferMap::Ptr &inMap, Json::Value &response, BufferMap::Ptr &outMap){
        return GetOutputInterface(request, inMap, response, outMap);
	}, false));

	method_map.emplace("GetMirrorPinCode", CRPCFuntion::CreateRpc([this](const Json::Value &request, const BufferMap::Ptr &inMap, Json::Value &response, BufferMap::Ptr &outMap){
        return GetMirrorPinCode(request, inMap, response, outMap);
	}, false));

	method_map.emplace("CloseCurrentLayout", CRPCFuntion::CreateRpc([this](const Json::Value &request, const BufferMap::Ptr &inMap, Json::Value &response, BufferMap::Ptr &outMap){
        return CloseCurrentLayout(request, inMap, response, outMap);
	}, false));

	IProtocolInterface::GetInstance()->RegistProtocol("Curtain", method_map);
}
bool CurtainServer::GetDeviceCapacity(const Json::Value &request, const BufferMap::Ptr &inMap, Json::Value &response, BufferMap::Ptr &outMap){
	//tracef("request is -------------------------> %s",request.toStyledString().c_str());

	Json::Value streamType;
	if(!Media::HttpCmdProcess::instance()->getDeviceCapacity(streamType)){
		response["data"]["Param"]["Result"] = false;
		return false;
	}
	response["data"]["Param"] = streamType;
	response["data"]["Param"]["Result"] = true;
	return true;
}

bool CurtainServer::GetStreamType(const Json::Value &request, const BufferMap::Ptr &inMap, Json::Value &response, BufferMap::Ptr &outMap){
	//tracef("request is -------------------------> %s",request.toStyledString().c_str());

	Json::Value streamType;
	if(!Media::HttpCmdProcess::instance()->getStreamType(streamType)){
		response["data"]["Param"]["Result"] = false;
		return false;
	}
	response["data"]["Param"] = streamType;
	//tracef("GetStreamType ---> %s\n", response.toStyledString().c_str() );
	response["data"]["Param"]["Result"] = true;
	return true;
}

bool CurtainServer::SetCurtainLayout(const Json::Value &request, const BufferMap::Ptr &inMap, Json::Value &response, BufferMap::Ptr &outMap){
	//tracef("request is -------------------------> %s",request.toStyledString().c_str());

	Media::HttpCmdProcess::instance()->setCurtainLayout(request["Param"]);

	tracef("SetCurtainLayout end\n");

	
	return true;
}

bool CurtainServer::GetCurtainLayout(const Json::Value &request, const BufferMap::Ptr &inMap, Json::Value &response, BufferMap::Ptr &outMap){
	//tracef("request is -------------------------> %s",request.toStyledString().c_str());

	Json::Value table;
	Media::HttpCmdProcess::instance()->getCurtainLayout(table);
	response["data"]["Param"]["Curtain"] = table;
	response["data"]["Param"]["Result"] = true;
	return true;
}

bool CurtainServer::SetPlayStrategy(const Json::Value &request, const BufferMap::Ptr &inMap, Json::Value &response, BufferMap::Ptr &outMap){
	//tracef("request is -------------------------> %s",request.toStyledString().c_str());

	if(Media::HttpCmdProcess::instance()->setPlayStrategy(request["Param"])){
		response["data"]["Param"]["Result"] = true;
		return true;
	}else{
		response["data"]["Param"]["Result"] = false;
		return false;
	}
}

bool CurtainServer::SetDeviceShareStatus(const Json::Value& request, const BufferMap::Ptr& inMap, Json::Value& response, BufferMap::Ptr& outMap) {
	//tracef("request is -------------------------> %s",request.toStyledString().c_str());

	if (Media::HttpCmdProcess::instance()->SetDeviceShareStatus(request["Param"])) {
		response["data"]["Param"]["Result"] = true;
		return true;
	}
	else {
		response["data"]["Param"]["Result"] = false;
		return false;
	}
}

bool CurtainServer::GetOutputInterface(const Json::Value &request, const BufferMap::Ptr &inMap, Json::Value &response, BufferMap::Ptr &outMap){
	tracef("request:%s\n", request.toStyledString().c_str());
	Json::Value outputInterfaces;
	if(!Media::HttpCmdProcess::instance()->getOutputInterface(outputInterfaces)){
		response["data"]["Param"]["Result"] = false;
		return false;
	}
	response["data"]["Param"] = outputInterfaces;
	//tracef("GetStreamType ---> %s\n", response.toStyledString().c_str() );
	response["data"]["Param"]["Result"] = true;
	return true;
}

bool CurtainServer::GetMirrorPinCode(const Json::Value &request, const BufferMap::Ptr &inMap, Json::Value &response, BufferMap::Ptr &outMap){
	string pinCode;
	if(!Media::HttpCmdProcess::instance()->getMirrorPinCode(pinCode)){
		return false;
	}
	response["data"]["Param"]["MirrorPinCode"] = pinCode;
	return true;
}


bool CurtainServer::CloseCurrentLayout(const Json::Value &request, const BufferMap::Ptr &inMap, Json::Value &response, BufferMap::Ptr &outMap){
	//判定设备当前是否在投屏
	if(Media::ScreenMirrorStream::instance()->getShareScreenStatus()){
		response["code"] = Media::ScreenPlaying;
		response["msg"] = "This operation is not allowed when the device is projecting the screen";
		errorf("The device is displaying screen mirroring information, please try again later\n");
		return false;
	}
	if(!Media::HttpCmdProcess::instance()->playDefaultCurtain()){
		return false;
	}
	return true;
}
